using System;
using System.Collections.Generic;
using System.Text;

namespace Barrage
{
    /// <summary>
    /// Base class for almost every element in the engine
    /// </summary>
    public abstract class Element:IDisposable
    {
        /// <summary>
        /// Renders the element (usually to screen)
        /// Do not override this method, use DoRender instead
        /// </summary>
        public void Render()
        {
            if (this.visible) DoRender();
        }
        /// <summary>
        /// Abstract method: Override this method to implement the render to screen
        /// </summary>
        protected abstract void DoRender();

        /// <summary>
        /// Updates the element (matrices, timers, etc)
        /// Do not override this method, use DoUpdate instead
        /// </summary>
        public void Update()
        {
            if (this.active) DoUpdate();
        }

        /// <summary>
        /// Override this method to implement additional updates of the element
        /// </summary>
        protected virtual void DoUpdate()
        {
            motion.Update();
        }

        
        bool active = true;
        /// <summary>
        /// Gets/Sets the element active status (if not active the item won't be updated on an Update call)
        /// </summary>
        public bool Active { get { return active; } set { active = value; } }

        bool visible = true;
        /// <summary>
        /// Gets/Sets the element visible status (if not visible the item won't be updated on an Render call)
        /// </summary>
        public bool Visible { get { return visible; } set { visible = value; } }

        /// <summary>
        /// The element's motion matrix
        /// </summary>
        protected Motion motion = new Motion();
        /// <summary>
        /// The element's motion matrix
        /// </summary>
        public Motion Motion { get { return motion; } }

        /// <summary>
        /// Element's parent if there's any
        /// </summary> 
        protected Element parent = null;

        /// <summary>
        /// Get the element's parent if there's any
        /// </summary> 
        public Element Parent { get { return parent; } }

        /// <summary>
        /// Clear resources and pointers to other objects
        /// </summary>
        public virtual void Dispose()
        {
            parent = null;
            NLog.LogManager.GetLogger(ToString()).Debug("Disposing");
            GC.SuppressFinalize(this);
        }
        /// <summary>
        /// Destructor. Clear resources and pointers to other objects
        /// </summary>
        ~Element()
        {
            Dispose();
        }

    }
}
